package com.gmail.amos.zuercher.StonemenMustDie.util;

import java.util.Vector;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

/**
 * Fieldclass 
 * @author Amos
 *
 */
public class Field {

	protected Vector<Location> locs;
	protected World world;
	
	public Field() {
		locs = new Vector<Location>();
	}
	
	/**
	 * Creates a field as playground for the deathmatch game. In fact the method only gets all blocks, along the rectangle edge between two given blocks. This blocks where saved in a vector.
	 * @param block1
	 * @param block2
	 * @return
	 */
	public boolean createField(Location block1, Location block2) {
		
		//First we need the Minecraft World to perform the createField method
		world = block1.getWorld();
		
		//Get block location from both blocks
		double b1x = block1.getX();
		double b1z = block1.getZ();
		double b1y = block1.getY();
		
		double b2x = block2.getX();
		double b2z = block2.getZ();
		double b2y = block2.getY();
		
		//Get the amount of loops to make to calculate the blocks for the field edge
		double divX = b1x - b2x;
		double divZ = b1z - b2z;
		
		//Two FOR Loops to get all Locations between Block1 and Block2
		for(int x = 0; x <= Math.abs(divX); x++) {
			Location loc1 = new Location(world, b2x, b1y, b1z);
			Location loc2 = new Location(world, b2x, b2y, b2z);
			if(b1x > b2x) {
				loc1.setX(b2x+x);
				loc2.setX(b2x+x);
			} else {	 
				loc1.setX(b1x+x);
				loc2.setX(b1x+x);
			}
			loc1 = this.checkBlockisEmpty(loc1);				
			loc2 = this.checkBlockisEmpty(loc2);
			locs.add(loc1);
			locs.add(loc2);
		}
		for(int z = 0; z < Math.abs(divZ); z++) {
			Location loc1 = new Location(world, b1x, b1y+1, b2z+z);
			Location loc2 = new Location(world, b2x, b2y+1, b2z+z);
			if(b1z > b2z) {
				loc1.setZ(b2z+z);
				loc2.setZ(b2z+z);
			} else {
				loc1.setZ(b1z+z);
				loc2.setZ(b1z+z);
			}
			loc1 = this.checkBlockisEmpty(loc1);
			loc2 = this.checkBlockisEmpty(loc2);
			locs.add(loc1);
			locs.add(loc2);
		}
		for(Location loc : locs) {
			Block block = loc.getBlock();
			block.setType(Material.FENCE);
		}
		return true;
	}
	
	/**
	 * Method to search the next air block at a specific location given through X and Z position.
	 * @param loc 
	 * @return
	 */
	private Location checkBlockisEmpty(Location loc) {
		if(loc.getBlock().isEmpty()) {
			Location tmpLoc = new Location(world, loc.getX(), loc.getY()-1, loc.getZ());
			if(world.getBlockAt(tmpLoc).isEmpty()) {
				return checkBlockisEmpty(tmpLoc);
			} else {
				return loc;
			}
		} else {
			loc.setY(loc.getY()+1);
			return checkBlockisEmpty(loc);
		}
	}
	
	public boolean playerIsInField(Player player) {
		
		Location highestPoint = null;
		Location lowestPoint = null;
		
		for(Location loc : locs) {
			if(highestPoint == null) {
				highestPoint = loc;
			}
			
			if(lowestPoint == null) {
				lowestPoint = loc;
			}
			
			if(loc.getX() > highestPoint.getX() || loc.getZ() > highestPoint.getZ()) {
				highestPoint = loc;
			}
			
			if(loc.getX() < lowestPoint.getX() || loc.getZ() < lowestPoint.getZ()) {
				lowestPoint = loc;
			}
		}
		
		if(player.getLocation().getX() < highestPoint.getX() && player.getLocation().getX() > lowestPoint.getX()) {
			if(player.getLocation().getZ() < highestPoint.getZ() && player.getLocation().getZ() > lowestPoint.getZ()) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	
	public boolean locationIsInField(Location location) {
		
		Location highestPoint = null;
		Location lowestPoint = null;
		
		for(Location loc : locs) {
			if(highestPoint == null) {
				highestPoint = loc;
			}
			
			if(lowestPoint == null) {
				lowestPoint = loc;
			}
			
			if(loc.getX() > highestPoint.getX() || loc.getZ() > highestPoint.getZ()) {
				highestPoint = loc;
			}
			
			if(loc.getX() < lowestPoint.getX() || loc.getZ() < lowestPoint.getZ()) {
				lowestPoint = loc;
			}
		}
		
		if(location.getX() < highestPoint.getX() && location.getX() > lowestPoint.getX()) {
			if(location.getZ() < highestPoint.getZ() && location.getZ() > lowestPoint.getZ()) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
	
	
	/**
	 * Reset the playground.
	 * @return
	 */
	public boolean resetField() {
		for(Location loc : locs) {
			Block block = loc.getBlock();
			block.setType(Material.AIR);
		}
		try
		{
			locs.clear();
			return true;
		}
		catch (Exception e) {
			return false;
		}
		
	}
}
